/*
 * Copyright (C) 2020 The LINN Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */

package com.juqimiao.linn.domain;

import com.juqimiao.linn.context.ApplicationContextWrapperI;
import com.juqimiao.linn.utils.IdGeneratorI;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 *
 * Todo: 需要雪花算法支持生产分布式全局id。
 * Todo: 考虑使用雪花算法生产uid.
 *
 * 构建一个{@link AggregatorI}对象的工厂类。
 *
 * <p>一个 EntityFactory 只需要具有狗爪有效{@link AggregatorI}所需要的那些属性。对于固定规则不关心的细节，可以之后在添加。</p>
 *
 * <p>
 * 工厂的职责：
 * 1. 通常，对于一个Entity而言，它需要一个全局范围类唯一的Id，虽然这个Id不是由工厂负责生成，
 * 但工厂需要知道需要什么样的标识，以及将标识放在何处。
 *
 * 2. 用于重建对象的Factory与用于创建对象的Factory很类似，但也有区别。
 *    1) 用户创建对象的Factory，需要知晓如何提供一个跟踪ID，而用于重建对象的Factory不分配新的跟踪Id。
 *    如果重新分配ID将丢失与先前对象的连续性。因此在重建对象的Factory中，标识属性必须是输入参数的一部分。
 *
 *    2) 当固定规则未满足时，重建对象的Factory需要采取不同的方式进行处理。
 *    当创建新对象时，如果未满足固定条件，Factory将拒绝创建对象。
 *
 *    3)重建对象可以配合repository从数据库或其他存储方式中重建。
 *
 *    4)Factory封装了对象创建和重建时的生命周期转换，这种转换需要repository来协助对象与存储之间的相互转换。
 * </p>
 *
 * @author Collin Cai
 */
@Component
public abstract class EntityFactory<T extends AggregatorI> {

    @Autowired
    private ApplicationContextWrapperI wrapperI;

    @Autowired
    private IdGeneratorI idGeneratorI;

    public T create(Class<T> entityClz) {
        return wrapperI.getBean(entityClz);
    }

    protected String generateStrId() {
        return idGeneratorI.nextStrId();
    }

    protected long generateId() {
        return idGeneratorI.nextId();
    }
}
